#ifndef _COMMAND_H
#define _COMMAND_H

#include <QUndoCommand>
class RegionScene;
class Region;
class CommandPrivate;
class Command : public QUndoCommand
{
public:
	Command(Region* item, QUndoCommand *parent = 0);
	~Command();
public:
	enum 
	{
		CommandId = 1,
	};
public:
	int id() const { return CommandId;}
public:
	Region* regionItem() const;		
protected:
	QScopedPointer<CommandPrivate> d_ptr;
	Command(CommandPrivate &dd,					 
		QUndoCommand *parent = 0);
private:
	Q_DECLARE_PRIVATE(Command)	
};

class AddCommandPrivate;
class AddCommand : public Command
{
public:
	AddCommand(RegionScene *scene, Region* item, QUndoCommand *parent = 0);
	~AddCommand();
public:
	RegionScene* regionScene() const;
public:
	virtual void undo();
	virtual void redo();
private:
	Q_DECLARE_PRIVATE(AddCommand)	
};


class DelCommand : public AddCommand
{
public:
	DelCommand(RegionScene *scene, Region* item, QUndoCommand *parent = 0);
	~DelCommand();
public:
	virtual void undo();
	virtual void redo();
};

class MoveCommandPrivate;
class MoveCommand : public Command
{
public:
	MoveCommand(Region* item, const QPointF& distance, QUndoCommand *parent = 0);
	MoveCommand(const QList<Region*>& items, const QPointF& distance, QUndoCommand *parent = 0);
	~MoveCommand();
public:
	enum 
	{
		CommandId = 2,
	};
public:
	int id() const { return CommandId;}
public:
	QPointF distance() const;
	void setDistance(const QPointF& newPos);
public:
	virtual void undo();
	virtual void redo();
	virtual bool mergeWith(const QUndoCommand *command);
private:
	Q_DECLARE_PRIVATE(MoveCommand)	
};

class RotateItemCommandPrivate;
class RotateItemCommand : public Command
{
public:
	RotateItemCommand(Region* item, const qreal angle, QUndoCommand *parent = 0);
	RotateItemCommand(const QList<Region*>& items, const qreal angle, QUndoCommand *parent = 0);
	~RotateItemCommand();
public:
	enum 
	{
		CommandId = 3,
	};
public:
	int id() const { return CommandId;}
public:
	qreal rotateAngle() const;
	void setRotateAngle(const qreal& rotateAngle);
public:
	virtual void undo();
	virtual void redo();
	virtual bool mergeWith(const QUndoCommand *command);
private:
	Q_DECLARE_PRIVATE(RotateItemCommand)	
};

class RectangleAdjustCommandPrivate;
class Rectangle;
class RectangleAdjustCommand : public Command
{
public:
	RectangleAdjustCommand(Rectangle* item, 
		const QPointF& newPos, 
		const qreal newRotation, 
		const QSizeF& newSize, 
		QUndoCommand *parent = 0);
	~RectangleAdjustCommand();
public:
	enum 
	{
		CommandId = 4,
	};
public:
	int id() const { return CommandId;}
public:
	Rectangle* rectangleItem() const;
public:
	QPointF oldPos() const;
	void setOldPos(const QPointF& pos);
	QPointF newPos() const;
	void setNewPos(const QPointF& pos);
	qreal oldRotation() const;
	void setOldRotation(const qreal);
	qreal newRotation() const;
	void setNewRotation(const qreal);
	QSizeF newSize() const;
	void setNewSize(const QSizeF& );
	QSizeF oldSize() const;
	void setOldSize(const QSizeF& );
public:
	virtual void undo();
	virtual void redo();
	bool mergeWith(const QUndoCommand *command);
private:
	Q_DECLARE_PRIVATE(RectangleAdjustCommand)
};

class Ring;
class AdjustRingCommandPrivate;
class AdjustRingCommand : public Command
{
public:
	AdjustRingCommand(Ring* item, const QSizeF& newRingSize, QUndoCommand *parent = 0);
	~AdjustRingCommand();
public:
	enum 
	{
		CommandId = 5,
	};
public:
	int id() const { return CommandId;}
public:
	Ring* ringItem() const;
public:
	QSizeF newRingSize() const;
	void setNewRingSize(const QSizeF& );
	QSizeF oldRingSize() const;
	void setOldRingSize(const QSizeF& );
public:
	virtual void undo();
	virtual void redo();
	bool mergeWith(const QUndoCommand *command);
private:
	Q_DECLARE_PRIVATE(AdjustRingCommand)
};

class PolygonItem;
class AdjustPolygonCommandPrivate;
class AdjustPolygonCommand : public Command
{
public:
	AdjustPolygonCommand(PolygonItem* item, const int index,const QPointF& newPos, QUndoCommand *parent = 0);
	~AdjustPolygonCommand();
public:
	enum 
	{
		CommandId = 6,
	};
public:
	int id() const { return CommandId;}
public:
	PolygonItem* polygonItem() const;
public:
	int index() const;
	QPointF distance() const;
	void setDistance(const QPointF& );
public:
	virtual void undo();
	virtual void redo();
	bool mergeWith(const QUndoCommand *command);
private:
	Q_DECLARE_PRIVATE(AdjustPolygonCommand)
};

class RegionGroup;
class RegionGroupCommandPrivate;
class RegionGroupCommand : public Command
{
public:
	RegionGroupCommand(RegionScene* scene, const QList<Region*>& items, QUndoCommand *parent = 0);
	RegionGroupCommand(RegionScene* scene, RegionGroup* regionGroup, QUndoCommand *parent = 0);
	~RegionGroupCommand();
public:
	enum 
	{
		CommandId = 7,
	};
public:
	int id() const { return CommandId;}
public:
	RegionScene* regionScene() const;
	RegionGroup* regionGroup() const;
	void setRegionGroup(RegionGroup*);
public:
	virtual void undo();
	virtual void redo();
private:
	Q_DECLARE_PRIVATE(RegionGroupCommand)
};

class RegionUngroupCommandPrivate;
class RegionUngroupCommand : public RegionGroupCommand
{
public:
	RegionUngroupCommand(RegionScene* scene, RegionGroup* regionGroup, QUndoCommand *parent = 0);
	~RegionUngroupCommand();
public:
	enum 
	{
		CommandId = 8,
	};
public:
	int id() const { return CommandId;}
public:
	virtual void undo();
	virtual void redo();
private:
	Q_DECLARE_PRIVATE(RegionGroupCommand)
};

//	class RegionUngroupCommand : public RegionGroupCommand

#endif // COMMAND_H
